<?php

/**
 * SelectTest
 *
 * @author vbolshov
 */

use km\db\Select;

require_once dirname(__FILE__) . '/../../lib/km/db/Select.php';

class StubRow {}

class SelectTest extends PHPUnit_Framework_TestCase {
	/**
	 * @var Select
	 */
	private $select;
	/**
	 * @var PDO
	 */
	private $pdo;
	
	private $test_data = array('foo', 'bar', 'buz',);
	
	function __construct()
	{
		parent::__construct();
		// @todo PDO setup should be configurable
		$this->pdo = new PDO('mysql:dbname=test', 'root', null, array(
			PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
		));
		Select::setDefaultConnection($this->pdo);
	}
	
	function testSelectAll()
	{
		$this->assertEquals(count($this->test_data), $this->select->count());
		$this->select->order('id');
		foreach ($this->select as $i => $row) {
			$this->assertEquals($i, $row['id']);
			$this->assertEquals($this->test_data[$i], $row['name']);
		}
	}
	
	function testSelectWithWhereCondition()
	{
		$this->select->where('id > ?', 0);
		$this->assertEquals(2, $this->select->count());
		$this->select->order('id');
		foreach ($this->select as $i => $row) {
			$this->assertEquals($this->test_data[$row['id']], $row['name']);
		}
	}
	
	function testSelectWithGroupByClause()
	{
		$this->select->group('id');
		$this->assertEquals(count($this->test_data), $this->select->count());
		$this->select->order('id');
		foreach ($this->select as $i => $row) {
			$this->assertEquals($i, $row['id']);
			$this->assertEquals($this->test_data[$i], $row['name']);
		}
	}
	
	function testSelectWithGroupByAndHavingClauses()
	{
		$this->select->group('id');
		$this->select->having('id = ?', 0);
		$this->assertEquals(1, $this->select->count('id'));
		$fetch = $this->select->fetchOne();
		$this->assertEquals(0, $fetch['id']);
		$this->assertEquals($this->test_data[0], $fetch['name']);
	}
	
	function testFetchModes()
	{
		$this->select->order('id');
		
		$this->select->setFetchMode(PDO::FETCH_ASSOC);
		$this->assertEquals(array('id' => 0, 'name' => 'foo'), $this->select->fetchOne());
		
		$this->select->setFetchMode(PDO::FETCH_BOTH);
		$this->assertEquals(array(0 => 0, 'id' => 0, 1 => 'foo', 'name' => 'foo'), $this->select->fetchOne());
		
		$this->select->setFetchMode(PDO::FETCH_KEY_PAIR);
		$this->assertEquals(array(0 => 'foo'), $this->select->fetchOne());
		
		$this->select->setFetchMode(PDO::FETCH_OBJ);
		$o = $this->select->fetchOne();
		$this->assertEquals(0, $o->id);
		$this->assertEquals('foo', $o->name);
		
		$this->select->setFetchMode(PDO::FETCH_CLASS, 'StubRow');
		$o = $this->select->fetchOne();
		$this->assertTrue($o instanceof StubRow);
		$this->assertEquals(0, $o->id);
		$this->assertEquals('foo', $o->name);
		
		$o = new StubRow();
		$this->select->setFetchMode(PDO::FETCH_INTO, $o);
		$fetched = $this->select->fetchOne();
		$this->assertEquals($o, $fetched);
		$this->assertEquals(0, $o->id);
		$this->assertEquals('foo', $o->name);
		
	}
	
	function setUp()
	{
		$this->tearDown();
		$this->pdo->query('CREATE TABLE test (id INT, name VARCHAR(100))');
		foreach ($this->test_data as $id => $name) {
			$this->pdo->query("INSERT INTO test (id, name) VALUES ($id, '$name')");
		}
		$this->select = new Select('test');
	}
	
	function tearDown()
	{
		$this->pdo->query('DROP TABLE IF EXISTS test');
	}
}